package com.study.springboot.config;

import com.study.springboot.factory.AddHeaderGatewayFilterFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import reactor.core.publisher.Mono;

import java.util.Objects;

/**
 * @author huyong
 * @Decription
 * @date 2025-03-21 17:34
 */
@Configuration
public class GateWayConfig {
    @Autowired
    private AddHeaderGatewayFilterFactory addHeaderGatewayFilterFactory;

    /**
     * 使用过滤器添加请求头
     */

    @Bean
    public RouteLocator filterAddRequestHeaderRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes().route("add_request_header", r -> r.path("/**").filters(f ->
                f.addRequestHeader("X-Request-Color", "Red")
                        .addRequestHeader("X-Request-Color", "Green")
                        .addRequestHeader("X-Request-Color", "Yellow")
                        //如果请求头已经存在不添加
                        .addRequestHeadersIfNotPresent("X-Request-Color-1:blue", "X-Request-Color-1:green", "X-Request-Color-1:red")
                        .addRequestHeadersIfNotPresent("X-Request-Color-2:pink", "X-Request-Color-2:org", "X-Request-Color-2:black")
                        //添加多个参数
                        .addRequestParameter("name", "李四")
                        .addRequestParameter("age", "50")
                        //给响应头添加信息
                        .addResponseHeader("X-Response-Color", "Red")
                        .addResponseHeader("X-Response-Color", "Green")
                        //添加自定义过滤器
                       // .filter(x-> Mono.just(addHeaderGatewayFilterFactory.apply(addHeaderGatewayFilterFactory.newConfig().)))
                        //使用降级过滤器 降级后转发到/fallback 路径下
                        .circuitBreaker(c -> c.setName("fullBack").setFallbackUri("forward:/fallback"))
                        //移除请路径的前两个 例如 /api/v1/info 去掉/api/v1
                        .stripPrefix(2)
                        //给请求路径默认添加一个前缀
                        .prefixPath("/info")
                        //路径的替换
                        .rewritePath("/api/v1/(?<segment>.*)", "${segment}")
                        //限流配置
                        //.requestRateLimiter(config->config.setKeyResolver(exchange -> Mono.just(Objects.requireNonNull(exchange.getRequest().getRemoteAddress()).getHostName()))
                        //        //参数1 每次产生多少个令牌 最大每次产生20个，每次消耗令牌 1个
                        //)


        ).uri("http://127.0.0.1:7999/")).build();
    }



    /**
     * 权重匹配
     */
    //@Bean
    //public RouteLocator weightRouteLocator(RouteLocatorBuilder builder) {
    //    //根据权重路由到不同的机器上  可以用来灰度发布，切换流量
    //    return builder.routes()
    //            .route("weight_provider_8001", r -> r.weight("provider_group", 1).uri("http://127.0.0.1:8081/"))
    //            .route("weight_provider_8002", r -> r.weight("provider_group", 9).uri("http://127.0.0.1:8082/"))
    //            .build();
    //}
    /**
     * 请求参数的匹配
     */
    //@Bean
    //public RouteLocator queryRouteLocator(RouteLocatorBuilder builder) {
    //    //参数以 customer或 provider开头进行匹配
    //    return builder.routes()
    //            .route("query_consumer", r -> r.query("name", "consumer.+").and().query("size").uri("http://127.0.0.1:8080/"))
    //            .route("query_provicer", r -> r.query("name", "provicer.+").uri("http://127.0.0.1:8081/")).build();
    //}
    /**
     * 路径匹配
     */
    //@Bean
    //public RouteLocator pathRouteLocator(RouteLocatorBuilder builder) {
    //    return builder.routes()
    //            .route("path_customer", r -> r.path("/api/v1/consumer/**").uri("http://127.0.0.1:8080/"))
    //            .route("path_provider", r -> r.path("/api/v1/provicer/**").uri("http://127.0.0.1:8081/")).build();
    //}
    /**
     * 请求提交方式进行过滤
     * @param builder
     * @return
     */
    //@Bean
    //public RouteLocator methodLocator(RouteLocatorBuilder builder) {
    //    //使用场景 不同用户访问不同的域名
    //    return builder.routes().route("host_route", r -> r.method(HttpMethod.POST, HttpMethod.GET,HttpMethod.DELETE,HttpMethod.OPTIONS).uri("http://127.0.0.1:8081/")).build();
    //}
    //@Bean
    //public RouteLocator hostRouteLocator(RouteLocatorBuilder builder) {
    //    //使用场景 不同用户访问不同的域名
    //    return builder.routes().route("host_route", r -> r.host("aaa.com:9001","bbb.com:9001").uri("http://127.0.0.1:8081/")).build();
    //}
    //@Bean
    //public RouteLocator headerRouteLocator(RouteLocatorBuilder builder) {
    //    return builder.routes().route("header_route", r -> r.header("X-Request-Id", "\\d+").and().header("Color", "gr.+").uri("http://127.0.0.1:8081/")).build();
    //}
    ///**
    // * 表示这个请求的cookie是这个值才合法
    // *
    // * @param builder
    // * @return
    // */
    //@Bean
    //public RouteLocator cookieRouteLocator(RouteLocatorBuilder builder) {
    //    return builder.routes().route("cookie_route", r -> r.cookie("city", "beijing").uri("http://127.0.0.1:8081/")).build();
    //}

    ///**
    // * 定义一个路由规则
    // *
    // * @param builder 构建器
    // */
    //@Bean
    //public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
    //    RouteLocatorBuilder.Builder routes = builder.routes();
    //    routes.route("baidu_route", r -> r.path("/bd").uri("http://www.baidu.com")).build();
    //    routes.route("jd_route", r -> r.path("/jd").uri("http://www.jd.com")).build();
    //    return routes.build();
    //}
    //
    ///**
    // * 表是在这个时间之后的请求才合法
    // *
    // * @param builder
    // * @return
    // */
    //@Bean
    //public RouteLocator afterRouteLocator(RouteLocatorBuilder builder) {
    //    RouteLocatorBuilder.Builder routes = builder.routes();
    //    //当前时间减3秒 将系统默认时区设置为当前时区 使用场景 : 抢票 只能在8点以后 才能访问 这里可以使用网关校验
    //    ZonedDateTime zonedDateTime = LocalDateTime.now().minusSeconds(3).atZone(ZoneId.systemDefault());
    //    routes.route("after_route", r -> r.after(zonedDateTime).uri("http://127.0.0.1:8081/")).build();
    //    return routes.build();
    //}
    //
    ///**
    // * 表示在这个时间之前的请求才合法
    // *
    // * @param builder
    // * @return
    // */
    //@Bean
    //public RouteLocator beforeRouteLocator(RouteLocatorBuilder builder) {
    //    RouteLocatorBuilder.Builder routes = builder.routes();
    //    ZonedDateTime zonedDateTime = LocalDateTime.now().plusDays(3).atZone(ZoneId.systemDefault());
    //    routes.route("before_route", r -> r.before(zonedDateTime).uri("http://127.0.0.1:8081/")).build();
    //    return routes.build();
    //}
    //
    ///**
    // * 表示在这个时间段内的请求才合法
    // *
    // * @param builder
    // * @return
    // */
    //@Bean
    //public RouteLocator betweenRouteLocator(RouteLocatorBuilder builder) {
    //    RouteLocatorBuilder.Builder routes = builder.routes();
    //    //例如电商的 促销时间范围
    //    ZonedDateTime startDateTime = LocalDateTime.now().minusSeconds(3).atZone(ZoneId.systemDefault());
    //    ZonedDateTime endDateTime = LocalDateTime.now().plusDays(3).atZone(ZoneId.systemDefault());
    //    routes.route("between_route", r -> r.between(startDateTime, endDateTime).uri("http://127.0.0.1:8081/")).build();
    //    return routes.build();
    //}

    /**
     * 定义限流的键 这里是请求参数中的用户 也可以使用ip
     */
    // @Bean
    KeyResolver userKeyResolver() {
        return exchange -> Mono.just(Objects.requireNonNull(exchange.getRequest().getQueryParams().getFirst("user")));
    }

    /**
     * 根据ip限流
     */
   // @Bean
    KeyResolver hostKeyResolver() {
        return exchange -> Mono.just(Objects.requireNonNull(exchange.getRequest().getRemoteAddress()).getHostName());
    }

    /**
     * 根据请求路径进行限流
     */
    //  @Bean
    KeyResolver pathKeyResolver() {
        return exchange -> Mono.just(Objects.requireNonNull(exchange.getRequest().getPath().value()));
    }
}
